package com.sunnuwell.demo.controller;

import com.alibaba.fastjson.JSON;
import com.sunnuwell.demo.annotation.PassToken;
import com.sunnuwell.demo.annotation.UserLoginToken;
import com.sunnuwell.demo.common.exception.AdException;
import com.sunnuwell.demo.common.utils.ListOnceUtils;
import com.sunnuwell.demo.common.utils.Utils;
import com.sunnuwell.demo.constant.Constants;
import com.sunnuwell.demo.entity.Resource;
import com.sunnuwell.demo.entity.Role;
import com.sunnuwell.demo.entity.User;
import com.sunnuwell.demo.entity.UserToken;
import com.sunnuwell.demo.repository.UserRepository;
import com.sunnuwell.demo.service.UserService;
import com.sunnuwell.demo.vo.UserRquest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletRequest;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

//使用@Controller 才可以返回html页面，使用@ResController 返回的是字符串
@Slf4j
@RestController
@RequestMapping("/api/v1")
public class UserController {

    @Autowired
    private UserService userService;

    /**
     * @Description: 登录
     * @Param: [user]
     * @return: com.sunnuwell.demo.common.vo.CommonResponse
     * @Author: Mr.Lv
     * @Date: 2019/4/26
     */
    @PostMapping(value = "/login")
    @PassToken
    public Map login(@RequestBody UserRquest user) throws AdException {
        log.info("UserController: register -> {}",
                JSON.toJSONString(user));
        //根据用户名查询，用户是否存在
        User user2 = userService.findByUsername(user);
        //如果存在
        if (user2 != null) {
            if (!user2.getPassword().equals(user.getPassword())) {
                //密码不正确,也可以换成判断验证码
                throw  new AdException(201,"密码不正确");
            } else {
                Map<String, Object> result = new HashMap<>();
                //如果密码正确，执行登录流程，返回token
                String token = Utils.getToken(user2);
                //将token插入到数据库中(暂时代替redis中的token)
                UserToken userToken = new UserToken();
                userToken.setUid(user2.getCid());
                userToken.setToken(token);
                // 保存token信息
                userService.saveToken(userToken);
                result.put("token", token);
                result.put("user", user2);
                return result;
            }
        } else {
            // 返回用户不存在
            log.info("UserController: register -> {}",
                    "用户不存在");
            throw  new AdException(404,"用户不存在");
        }
    }


    /**
     * @Description: 注册 / 添加用户
     * @Param: [user]
     * @return: com.sunnuwell.demo.common.vo.CommonResponse
     * @Author: Mr.Lv
     * @Date: 2019/4/26
     */
    @PostMapping(value = "/register")
    @PassToken
    public String resig(@RequestBody UserRquest user) throws AdException {
        log.info("UserController: register -> {}",
                JSON.toJSONString(user));
        //根据昵称查询，用户是否存在
        User user2 = userService.findByUsername(user);
        //若存在
        if (user2 != null) { //昵称重复
            throw new AdException(-1,Constants.ErrorMsg.SAME_NAME_ERROR);
        }
        //注册
        userService.save(user);
        return Constants.ErrorMsg.OPERATION_SUCCESS;
    }

    /**
     * @Description: 获取用户列表/通过用户名搜索
     * @Param: [userRequest]
     * @return: org.springframework.data.domain.Page<com.sunnuwell.demo.entity.User>
     * @Author: Mr.Lv
     * @Date: 2019/4/26
     */
    @ResponseBody
    @PostMapping("/getAllUser")
    @UserLoginToken
    public Page<User> getAllUser(@RequestBody UserRquest userRequest) throws AdException {
        log.info("UserController: updateUser -> {}",
                JSON.toJSONString(userRequest));
        return userService.findAll(userRequest);
    }

    /**
     * @Description: 修改用户
     * @Param: [userRequest]
     * @return: com.sunnuwell.demo.entity.User
     * @Author: Mr.Lv
     * @Date: 2019/4/26
     */
    @ResponseBody
    @PutMapping("/updateUser")
    @UserLoginToken
    public String updateUser(@RequestBody UserRquest userRequest) throws AdException {
        log.info("UserController: updateUser -> {}",
                JSON.toJSONString(userRequest));
        if (userRequest.getCid() == null) {
            throw new AdException(-1,Constants.ErrorMsg.REQUEST_PARAM_ERROR);
        }
        userService.update(userRequest);
        return Constants.ErrorMsg.OPERATION_SUCCESS;
    }


    /**
     * @Description: 删除用户
     * @Param: [cid]
     * @return: com.sunnuwell.demo.common.vo.CommonResponse
     * @Author: Mr.Lv
     * @Date: 2019/4/26
     */
    @ResponseBody
    @PutMapping("/deleteUser")
    @UserLoginToken
    public String deleteUser(@RequestBody UserRquest userRequest) throws AdException {
        log.info("UserController: deleteUser:uid -> {}",
                JSON.toJSONString(userRequest));
        if (userRequest.getCid() == null) {
            throw new AdException(-1,"缺少参数");
        }
        userService.deleteUser(userRequest);
        return Constants.ErrorMsg.OPERATION_SUCCESS;

    }


    /**
     * @Description: 根据用户token获取菜单
     * @Param: [httpServletRequest]
     * @return: com.sunnuwell.demo.common.vo.CommonResponse
     * @Author: Mr.Lv
     * @Date: 2019/4/29
     */
    @PostMapping("/getRoleResource")
    @UserLoginToken
    public List<Resource> getUserRoleResource(HttpServletRequest httpServletRequest) throws AdException {
        String token = httpServletRequest.getHeader("authorization");// 从 http 请求头中取出 token
        User user = userService.checkUserToken(token);
        // 提取user中的角色集合，求其并集，并且去重
        List<Role> roles = user.getRoleList();
        List<Resource> resources = new ArrayList<>();
        for (Role role : roles
                ) {
            for (Resource res : role.getResources()
                    ) {
                resources.add(res);
            }
        }
        return ListOnceUtils.removeDuplicate(resources);
    }
}